#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1000005;
int d[N];
int v[N];
int a[N];
int p[N];
int tp[N];
int n,m,L,V;
struct node{
    int l,r;
}qj[N];
int get(int l,int r){
    if(l>r) return 0;
    int ans=p[min(L,r)];
    if(l>0) ans-=p[l-1];
    return ans;
}
bool cmp(node a,node b){
    return a.l>b.l;
}
void work(int x){
    cin>>n>>m>>L>>V;
    for(int i=1;i<=n;i++) cin>>d[i]>>v[i]>>a[i];
    for(int i=0;i<=L;i++) p[i]=0;
    for(int i=1;i<=m;i++){
        cin>>tp[i];
        p[tp[i]]=1;
    }
    for(int i=1;i<=L;i++) p[i]+=p[i-1];
    int ans=0;
    for(int i=1;i<=n;i++){
        if(a[i]==0){
            if(v[i]<=V){
                qj[i].l=L+1;
                qj[i].r=-1;
            }else{
                qj[i].l=d[i];
                qj[i].r=L;
            }
        }else if(a[i]>0){
            if(v[i]>V){
                qj[i].l=d[i];
                qj[i].r=L;
            }else{
                int s=(V*V-v[i]*v[i])/(2*a[i])+1+d[i];
                qj[i].l=s;
                qj[i].r=L;
            }
        }else{
            if(v[i]<=V){
                qj[i].l=L+1;
                qj[i].r=-1;
            }else{
                int s=abs(V*V-v[i]*v[i])/abs(2*a[i])+d[i];
                if(abs(V*V-v[i]*v[i])%abs(2*a[i])==0) s--;
                qj[i].l=d[i];
                qj[i].r=s;
            }
        }
        qj[i].l=max(qj[i].l,0ll);
        qj[i].r=min(qj[i].r,L);
        if(get(qj[i].l,qj[i].r)>0) ans++;
        else{
            qj[i].l=0;
            qj[i].r=L+1;
        }
    }
    cout<<ans<<' ';
    ans=0;
    sort(qj+1,qj+n+1,cmp);
    int t=L+1;
    for(int i=1;i<=n;i++){
        if(qj[i].r>=t) continue;
        ans++;
        t=tp[lower_bound(tp+1,tp+m+1,qj[i].l)-tp];
    }
    cout<<m-ans<<'\n';
}
signed main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int T;
    cin>>T;
    while(T--) work(T);
    return 0;
}
/*
1
5 5 15 3
0 3 0
12 4 0
1 1 4
5 5 ‐2
6 4 ‐4
2 5 8 9 15
*/